package com.ztesoft.web.taskgenerator.taskjob;


import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.annotation.Resource;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.ztesoft.core.cache.EhCacheService;
import com.ztesoft.framework.exception.BaseAppException;
import com.ztesoft.framework.log.ZTEsoftLogManager;
import com.ztesoft.framework.util.DateUtils;
import com.ztesoft.framework.util.Utils;
import com.ztesoft.web.baseconfig.db.po.DmDataStatePO;
import com.ztesoft.web.baseconfig.db.po.DmPlanPO;
import com.ztesoft.web.baseconfig.service.IDmDataStateService;
import com.ztesoft.web.baseconfig.service.IDmPlanService;
import com.ztesoft.web.common.DMSConstant;
import com.ztesoft.web.taskgenerator.db.dao.DmTaskDao;
import com.ztesoft.web.taskgenerator.db.po.DmTaskPO;
import com.ztesoft.web.taskgenerator.service.IDmTaskService;
@Service
public class DmTaskFatherJob{
	
	private static final ZTEsoftLogManager logger = ZTEsoftLogManager
	            .getLogger(DmTaskFatherJob.class);
	
	@Autowired
	private IDmPlanService iDmPlanService;
	
	@Autowired
	private IDmTaskService iDmTaskService;
	
	@Autowired
	private IDmDataStateService iDmDataStateService;
	
	@Autowired
	private DmTaskDao dmTaskDao;
	
	
	@Resource(name = "frameworkEhCacheService")
	private EhCacheService dmsCacheService;
	
	public void createFatherTask(){
		logger.debug("新增任务表信息||start...");
		List<DmPlanPO> dsList;
		Integer dmPlanId;
		Integer groupNbr;
		StringBuffer sb = new StringBuffer();//StingBuffer用于存放任务开始执行时间
		List<DmTaskPO> dtLst = new ArrayList<DmTaskPO>();//构造List存放批量新增的任务实例
		List<DmTaskPO> dmTaskFrequency;
		try {
			/*1.任务生成器扫描数据管理计划表(DM_PLAN)和数据管理计划
			 * 和关系表(DM_PLAN_RELATION)，获取当前有效的计划和策略记录*/
			dsList = iDmPlanService.selectByDmPlanAndGroupNbr();
			if(dsList!=null && dsList.size()>0){
				//循环每条取得的记录
				for (DmPlanPO dmPlanPO : dsList) {
					dmPlanId = dmPlanPO.getDmPlanId();
					groupNbr = dmPlanPO.getGroupNbr();
					
					// 判断是否已经数据恢复完成
					//Integer state = (Integer) dmsCacheService.get("dmsCache", "dataRecovery_"+dmPlanId);
					DmDataStatePO dds = iDmDataStateService.selectByPrimaryKey(dmPlanId);
					if (Utils.notEmpty(dds)) {
						Integer state = dds.getState();
						if (state == 1 || state == 2 || state == 4) {
							logger.debug("数据恢复状态为" + state);
							continue;
						}
//						// 判断同一个计划下，多个策略组，多个任务，的其他任务是否也已经数据恢复完成
//						boolean isOK = false;
//						if (state == 3) {
//							DmTaskPO dtPO = dmTaskDao.selectBydmPlanId(dmPlanId).get(0);
//							if (dtPO.getDmTaskId() != dds.getDmTaskId()) {// 不是最后一个，说明还没有全部数据恢复完成
//								isOK = true;
//							}
//						}
//						if (isOK) {
//							continue;
//						}
					}
					
					/*2.2）	使用DM_PLAN_ID、GROUP_NBR查询DM_TASK，查看是否有记录*/
					Integer count = iDmTaskService.countByArg(dmPlanId, groupNbr);
					DmPlanPO dmPlan = iDmPlanService.selectByPrimaryKey(dmPlanId);
					if(count!=null && count>0){
						dmTaskFrequency = iDmTaskService.selectByTaskInfoNotState(dmPlanId, groupNbr);
						if(!Utils.isEmpty(dmTaskFrequency)){
							DmTaskPO  task = dmTaskFrequency.get(0);
							if ((int)task.getIsCheck() == 1) {
								continue; //任务拒绝的不再生成下个周期性任务~
							}
							if ("00A".equals(task.getState()) || "00C".equals(task.getState())) {//完成、取消的生成下个周期
								
								if ("1".equals(dmPlan.getExecType()) ) {//自动执行	~ 且循环执行
									if ("0".equals(dmPlan.getExecFrequency())) {										
										sb = getScheduleDateByDmTask(task.getScheduleDate(), dmPlan);
									} else {//单次~
										if (dmPlan.getCycleDay() == null && (int)task.getPriority() == 2) {// 用循环周期和上个任务执行方式如果是自动过滤
											continue;
										}
										sb = getScheduleDateByFirstTask(dmPlan);
									}
								} else {
									continue;
								}
							} else {
								continue;
							}
						}else{
							continue;
						}
					}else{
						/*2-1.如果该策略是第一次生成任务,如果是第一次生成该任务的话通过数据
						 * 管理计划循环类型判断，如果是按月循环时，根据生效时间(DM_PLAN.EFF_DATE)，
						 * 计算生效年月+计划的开始时间(DM_PLAN.STATE_TIME)+00，
						 * 如果是按天循环，根据生效时间，计算生效年月日+计划的开时间(DM_PLAN.STATE_TIME)+00。
						 * 得到第一次生成任务的计划执行开始时间
						 */
						if ("1".equals(dmPlan.getExecType())) {//自动执行	~								
							sb = getScheduleDateByFirstTask(dmPlan);
						}
					}
					
					DmTaskPO dmTaskPO = new DmTaskPO();
					dmTaskPO.setDmPlanId(dmPlanPO.getDmPlanId());
					dmTaskPO.setGroupNbr(dmPlanPO.getGroupNbr());
					dmTaskPO.setSourceType(dmPlan.getSourceType());//源数据类型
					dmTaskPO.setPriority(getMapInfo(dmPlan).get("priority"));
					if ("1".equals(dmPlan.getExecType())) {//自动执行	~
						dmTaskPO.setScheduleDate(getScheduleDate(sb, dmPlan.getSpecialDay()));
						dmTaskPO.setName(getTaskName(dmPlan, groupNbr, getScheduleDate(sb, dmPlan.getSpecialDay())));//根据周期来计算
					} else {
						dmTaskPO.setName(getTaskName(dmPlan, groupNbr, new Date())+"-手工");//根据当前时间来计算
					}
					dmTaskPO.setIsCheck(getMapInfo(dmPlan).get("needCheck"));//是否需要审核
					dmTaskPO.setNodeId(dmPlan.getNodeId());
					dmTaskPO.setOperType(dmPlan.getOperType());
					dtLst.add(dmTaskPO);
				}
				//批量更新任务
				if(!Utils.isEmpty(dtLst)){
					iDmTaskService.addBatch(dtLst);
					logger.info("新增任务表信息||end...");
				}
			}
		} catch (BaseAppException e) {
			logger.error("BaseAppException ", e);	
		} catch (ParseException e) {
			logger.error("ParseException ", e);	
		}
	}

	private StringBuffer getScheduleDateByDmTask(Date oldScheduleDate, DmPlanPO dmPlanPO) {
		StringBuffer sb = new StringBuffer();
		String startTime = dmPlanPO.getStartTime();
		SimpleDateFormat cycleSdf =   new SimpleDateFormat(DateUtils.STR_DATE_FORMAT_DAY_WITH_SPLIT);//yyyy-MM-dd 
		Calendar c = Calendar.getInstance(); 
		c.setTime(oldScheduleDate);  
		if("0".equals(dmPlanPO.getCycleType())){//0--循环类型月 1--循环类型天 
			c.add(c.MONTH, dmPlanPO.getCycleDay());//加上循环周期
		}else{
			c.add(c.DATE, dmPlanPO.getCycleDay());
		}
		Date temp_date = c.getTime();   
		String cycleDate = cycleSdf.format(temp_date);
		
		if("0".equals(dmPlanPO.getCycleType())){//按月循环
			sb.append(cycleDate.substring(0, 7)).append("-").append(startTime.substring(0, 2)).
			append(" ").append(startTime.substring(2, 4)).
			append(":").append(startTime.substring(4, 6)).append(":00");
		}else{
			sb.append(cycleDate).append(" ").append(startTime.substring(2, 4)).append(":").
			append(startTime.substring(4, 6)).append(":00");//yyyy-mm-dd hh:mm:ss 开始执行时间格式
		}
		logger.debug("cycleType"+dmPlanPO.getCycleType()+"循环任务计划开始执行时间"+sb.toString());
		return sb;
	}
	
	private StringBuffer getScheduleDateByFirstTask(DmPlanPO dmPlanPO) {
		SimpleDateFormat cycleSdf =   new SimpleDateFormat(DateUtils.STR_DATE_FORMAT_DAY_WITH_SPLIT);//yyyy-MM-dd 
		//String effDate =  cycleSdf.format(dmPlanPO.getEffDate());
		String nowDate = cycleSdf.format(new Date());
		String startTime = dmPlanPO.getStartTime();
		StringBuffer sb = new StringBuffer();
		if("0".equals(dmPlanPO.getCycleType())){//按月循环
			sb.append(nowDate.substring(0, 7)).append("-").
			append(startTime.substring(0, 2)).
			append(" ").
			append(startTime.substring(2, 4)).append(":").append(startTime.substring(4, 6)).
			append(":00");
		}else{
			sb.append(nowDate.substring(0, 10)).
			append(" ").
			append(startTime.substring(2, 4)).append(":").append(startTime.substring(4, 6)).
			append(":00");
		}
		logger.debug("cycleType"+dmPlanPO.getCycleType()+"第一次任务计划开始执行时间"+sb.toString());
		return sb;
	}
	/**
	 * //排除计划表中的特殊日期
	 * @param sb
	 * @param specialDay
	 * @return
	 * @throws ParseException
	 */
	private Date getScheduleDate(StringBuffer sb, String specialDay) throws ParseException{
		SimpleDateFormat newsdf =  new SimpleDateFormat(DateUtils.STR_DEFAULT_DATE_FORMAT_WITH_SPLIT);//yyyy-MM-dd HH:mm:ss 
		Date scheduleDate;
		Long day ;
		scheduleDate = newsdf.parse(sb.toString());
		day = Long.valueOf(newsdf.format(scheduleDate).substring(8, 10));
		Calendar c = Calendar.getInstance(); 
		//排除计划表中的特殊日期
		List<Long> specialDayLst = new ArrayList<Long>();
		 if(null != specialDay && specialDay.length() > 0) {
			 for(String s : specialDay.split(",")) {
				 specialDayLst.add(Long.valueOf(s));
			 }
		 }
		 
		 for (Long spDay : specialDayLst) {
			if(day.equals(spDay)){
				 c.setTime(scheduleDate);  
				 c.add(c.DATE, 1);  
				 scheduleDate = c.getTime();  
				 day = Long.valueOf(newsdf.format(scheduleDate).substring(8, 10));
			}
		}
		return scheduleDate;
	}
	
	private Map<String, Integer> getMapInfo(DmPlanPO dmPlan){
		Map<String, Integer> map = new HashMap<String, Integer>();
		Integer priority;
		if(DMSConstant.EXEC_TYPE_AUTO.equals(dmPlan.getExecType())){//若计划为自动执行，则填为2；
			priority = DMSConstant.PRIORITY_AUTO;
		}else{//若计划为手工执行，则填为1；
			priority = DMSConstant.PRIORITY_HAND;
		}
		Integer needCheck;
		//是否审核通过
		if("F".equalsIgnoreCase(dmPlan.getNeedCheck())||dmPlan.getOperType()==2){//T需要确认==待审核,F不需要确认==审核通过
			needCheck = DMSConstant.IS_CHECK_PASS;
		}else{
			if(DMSConstant.SOURCE_TYPE_FILE  == dmPlan.getSourceType()){
				needCheck = DMSConstant.IS_CHECK_PASS;
			}else{
				needCheck = DMSConstant.IS_CHECK_DEALPASS;
			}
		}
		map.put("priority", priority);
		map.put("needCheck", needCheck);
		
		return map;
	}
	/**
	 * //任务名称根据计划名称+日期+组号
	 * @param dmPlan
	 * @return
	 */
	private String getTaskName(DmPlanPO dmPlan, Integer groupNbr, Date ScheduleDate){
		SimpleDateFormat sdf =  new SimpleDateFormat(DateUtils.STR_DATE_FORMAT_DAY_WITHOUT_SPLIT);//yyyy-MM 
		StringBuffer sbName = new StringBuffer();
		/*.append("-").append(InetAddress.getLocalHost())*/
		sbName.append(dmPlan.getPlanName()).append("-").append(sdf.format(ScheduleDate)).append("-").append(groupNbr);
		logger.debug("任务名称：||"+sbName.toString());
		return sbName.toString();

	}
}
